﻿using CommandLineParser;
using IndexedFilePackageLibrary;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace IfpReader
{
    static class Program
    {
        static void Main(string[] args)
        {
            var commandsErrs = new List<string>();
            var validator = new CommandLineValidator();
            validator.AcceptRawValueCount = int.MaxValue;
            validator.Options.Add(new CommandLineOption("file", 'f', true, false));
            validator.Options.Add(new CommandLineOption("name", 'n', true, false));
            validator.Options.Add(new CommandLineOption("out", 'o', true, false));
            validator.Options.Add(new CommandLineOption("count", 'c', false, false));
            if (!validator.TryParseAndValidate(Environment.CommandLine, commandsErrs))
            {
                PrintUsage();
                foreach (var err in commandsErrs)
                {
                    Console.WriteLine(err);
                }
                return;
            }

            string inputFile = validator.GetValue("file");
            string fileName = validator.GetValue("name");
            string outputFile = validator.GetValue("out");
            bool hasCount = validator.Contains("count");

            if (string.IsNullOrWhiteSpace(inputFile))
            {
                PrintUsage();
                Console.WriteLine("file not specified.");
                return;
            }
            if (string.IsNullOrWhiteSpace(fileName))
            {
                fileName = null;
            }
            if (string.IsNullOrWhiteSpace(outputFile))
            {
                outputFile = null;
            }

            if (!File.Exists(inputFile))
            {
                Console.WriteLine("file not exits.");
                return;
            }

            RunApp(inputFile, fileName, outputFile, hasCount);
        }

        static void PrintUsage()
        {
            Console.WriteLine("Usage: --file inputFile --name fileName --out outputFile");
        }

        static void RunApp(string inputFile, string fileName, string outputFile, bool showCountSwitch)
        {
            using (var package = IndexedFilePackage.Open(inputFile))
            {
                if (fileName == null)
                {
                    var nodes = package.FindAllNodes();
                    if (showCountSwitch)
                    {
                        Console.WriteLine(nodes.Count() + " file(s) in this package.");
                    }
                    else
                    {
                        int count = 0;
                        foreach (var item in nodes.OrderBy(i => i.FileName))
                        {
                            Console.WriteLine(item.FileName);
                            count++;
                        }
                    }
                    return;
                }

                var index = package.FindFile(fileName);
                if (index == null)
                {
                    Console.WriteLine($"file ({fileName}) not found.");
                    return;
                }

                var file = package.GetFileInfo(index);
                Console.WriteLine("FileName: " + file.FileName);
                Console.WriteLine("FileSize: " + file.FileSize);
                if (file.Attributes.HasValue)
                {
                    Console.WriteLine("Attributes: " + file.Attributes);
                }
                if (file.LastModifiedTimeUtc.HasValue)
                {
                    Console.WriteLine("LastModifiedTimeUtc: " + file.LastModifiedTimeUtc.Value.ToString());
                }

                if (outputFile != null)
                {
                    if (File.Exists(outputFile))
                    {
                        File.Delete(outputFile);
                    }

                    package.CopyFileTo(index, outputFile);
                }
            }
        }
    }
}
